(function(root, factory) {
    if (typeof define == "function" && define.amd)
        define(["baseTrack"], factory);
    else
        factory();
})(this, function(baseTrack) {
    this.legendofkage = this.legendofkage || {};
    baseTrack && (this.legendofkage.baseTrack = baseTrack);


    function BaiduTrack(map, opt) {
        var bdMap, numberMarker, evtMarkers = [],
            polyLineMarkers = [],
            trackData = {},
            historyTrackData = [],
            historyTrackPoints = [],
            intervalId, totalDistance = 0,
            lableDisText = '0公里',
            labelText = '',
            isHandleData = false;

        //轨迹状态
        var trackState = {
            playing: "playing",
            pause: "pause",
            stop: "stop",
            current: "stop"
        }

        //指明创建的marker类型
        var markerType = {
            personMarker: "personMarker",
            evtMarker: "evtMarker",
            numberMarker: "numberMarker"
        }

        var optSettings = {
            speed: 500, //播放速度
            calcDistance: false, //是否计算里程
            autoAdjustViewport: false, //轨迹播放超出边界时，是否自动调整视野(可见范围).
            baseUrl: "./images/", //人员或事件覆盖物相关图片根路径
            numberMarker: {
                url: '',
                size: new BMap.Size(21, 21),
                icon: null
            },
            evtMarker: {
                url: '',
                size: new BMap.Size(30, 39),
                icon: null
            },
            personMarker: {
                url: '',
                size: new BMap.Size(28, 45),
                icon: null,
                label: {
                    text: '',
                    offset: new BMap.Size(-5, -20),
                    style: {
                        backgroundColor: "#FFFFAD",
                        color: "#00000",
                        fontSize: 12,
                        fontName: "arial",
                        border: "none"
                    }
                }
            },
            polylineMarker: {
                strokeColor: "rgb(255, 0, 0)",
                strokeWeight: 2,
                strokeOpacity: 0.5
            }

        };

        BaiduTrack.__super__ && BaiduTrack.__super__.constructor.apply(this, arguments);

        if (!map) {
            throw new Error("构造函数中未传入地图对象!");
        }
        bdMap = map;
        opt = opt || {};
        if (!opt.dataSource) {
            throw new Error("配置对象未设置轨迹数据源!");
        }
        legendofkage.Util.extend(true, optSettings, opt);

        initMarker();
        listenTrackProcess.call(this);

        /*  创建marker，并返回
        	@type:marker类型,
        	@point:坐标点
        	@marker配置对象
        */
        function createMarker(type, point, opt) {
            opt = opt || {};
            Object.assign(optSettings[type], opt);
            var bdTrack = this;
            var marker = new BMap.Marker(point, optSettings[type]);
            if (type == markerType.evtMarker) {
                var keys = Object.keys(bdTrack.evtType);
                keys.forEach(function(item, index) {
                    if (item.indexOf(':') >= 0) {
                        marker.addEventListener(item.split(":")[1], function(e) {
                            bdTrack.dispatch(item, {
                                evtType: item.split(":")[1],
                                target: opt.evtMarker.data,
                                markerType: type
                            });
                        });
                    }
                })
            } else if (type == markerType.personMarker) {
                var labelContent = optSettings.calcDistance ? (labelText + ' ' + lableDisText) : labelText;
                var label = new BMap.Label(
                    labelContent, {
                        offset: optSettings.personMarker.label.offset
                    });
                label.setStyle(optSettings.personMarker.label.style);
                marker.setLabel(label);
            } else if (type == markerType.numberMarker) {
                var number = this.getId();
                var label = new BMap.Label(number, {
                    offset: new BMap.Size(5, 4)
                });
                label.setStyle({
                    border: 0,
                    background: "rgba(255,255,255,0)"
                });
                marker.setLabel(label);
            }
            return marker;
        }

        function createPolylineMarker(points, opt) {
            opt = opt || {};
            Object.assign(optSettings.polylineMarker, opt);
            var marker = new BMap.Polyline(points, optSettings.polylineMarker);
            return marker;
        };

        //配置默认的人员、事件、以及分段轨迹序号marker
        function initMarker() {
            var numMarker = optSettings.numberMarker;
            numMarker.url = optSettings.baseUrl + 'numberMarker.png';
            numMarker.icon = new BMap.Icon(numMarker.url, numMarker.size);

            var evtMarker = optSettings.evtMarker;
            evtMarker.url = optSettings.baseUrl + 'evt.png';
            evtMarker.icon = new BMap.Icon(evtMarker.url, evtMarker.size);

            var personMarker = optSettings.personMarker;
            personMarker.url = optSettings.baseUrl + 'walk_front.gif';
            personMarker.icon = new BMap.Icon(personMarker.url, personMarker.size);
            labelText = personMarker.label.text;
        }

        /*
			回放时取上下左右图标
			lat+ 上 lat- 下 lng+右 lng-左
    		这里就先比lng，若有左右差，则直接调用前后图片，若没前后差，才判断上下图片
	    */
        function adjustmentPersonMarkerDir(trackObj, obWalk) {
            //由于百度地图的marker.getIcon().setImageUrl有bug,并不能真正修改图片，故要达到此效果，
            //只有清除原有的marker,再新增一个	static
            var imageUrl = "";
            if (trackObj.lastNode != null) {
                var v_Lng = trackObj.point.lng - trackObj.lastNode.point.lng;
                var v_Lat = trackObj.point.lat - trackObj.lastNode.point.lat;

                if (v_Lng > 0) {
                    imageUrl = 'walk_right.gif';
                } else if (v_Lng < 0) {
                    imageUrl = 'walk_left.gif';
                } else if (v_Lat > 0) {
                    imageUrl = 'walk_back.gif';
                } else {
                    imageUrl = 'walk_front.gif';
                }
            } else if (obWalk) {
                imageUrl = obWalk;
            } else
                return;
            if (imageUrl.length > 0) {

                this.clearPersonMarker();
                optSettings.personMarker.url = optSettings.baseUrl + imageUrl;
                optSettings.personMarker.icon = new BMap.Icon(optSettings.personMarker.url, optSettings.personMarker.size);
                legendofkage.Util.extend(true, opt, optSettings.personMarker);
                this.personMarker = createMarker.call(
                    this,
                    markerType.personMarker,
                    trackObj.point
                );
                bdMap.addOverlay(this.personMarker);
            }
        };


        /**
         * 
         * 
         * @returns 
         */
        function getPersonIcon() {
            imageName = "walk_front_static.png";
            if (this.personMarker) {
                var image = this.personMarker.getIcon().imageUrl;
                if (image.indexOf('static') == -1) {
                    var index = image.lastIndexOf('/');
                    image = image.substr(index + 1);
                    imageName = image.split('.')[0] + "_static.png";
                } else
                    imageName = image;
            }
            return imageName;
        }

        //监听轨迹播放进度及状态
        function listenTrackProcess() {
            var track = this;
            track.on('processing', function(target) {
                if (trackState.current == trackState.pause) {
                    clearTimeout(intervalId);
                    //当播放完毕时，将gif动态图切换到png静态图
                    var point = track.personMarker.getPosition();
                    var iconImg = getPersonIcon.call(track);
                    adjustmentPersonMarkerDir.call(track, {
                        lastNode: null,
                        point: point
                    }, iconImg);
                }
            })
        }



        /*
			格式化轨迹数据(无论后台返回什么字段的数据，都要转化为统一要求的数据格式)
			@type:ListTP(格式化巡查员轨迹数据),ListTE(格式化事件数据)
	    */
        function formatTrackData(type, fn) {
            isHandleData = true;
            return optSettings.dataSource[type].map(function(item, index) {
                var obj = {
                    point: null,
                    date: null,
                    dateString: '',
                    tag: item
                };
                var newObj = fn(obj, item);
                if (newObj != obj) {
                    throw new TypeError("dataAdapter方法中回调函数返回错误的数据类型!");
                }
                if (!newObj.point || !newObj.date) {
                    throw new Error("dataAdapter方法中回调函数的返回对象属性值有误,其point,date属性均必须有值!");
                }
                newObj.__data__ = item;
                newObj.__type__ = type;
                newObj.__time__ = newObj.date.getTime(); //排序用
                return newObj;
            })
        }

        //循环绘制轨迹
        function drawTrack() {
            var trackObj = trackData.allData.shift();
            if (trackObj) {
                if (trackObj.__type__ == "ListTP") {
                    adjustmentPersonMarkerDir.call(this, trackObj);
                    this.personMarker.setPosition(trackObj.point);
                    if (optSettings.calcDistance) {
                        if (trackObj.lastNode != null) {
                            totalDistance += bdMap.getDistance(trackObj.lastNode.point, trackObj.point);
                            lableDisText = (totalDistance / 1000).toFixed(3) + "公里";
                            this.personMarker.getLabel().setContent(labelText + ' ' + lableDisText);
                        }
                    }

                    historyTrackPoints.push(trackObj.point);
                    //如果轨迹点超出了范围，就自动调整!
                    if (optSettings.autoAdjustViewport) {
                        var bound = bdMap.getBounds();
                        !bound.containsPoint(trackObj.point) && bdMap.setViewport(historyTrackPoints);
                    }
                    if (trackObj.lastNode != null) {
                        var polylineMarker = createPolylineMarker.call(this, [trackObj.lastNode.point, trackObj.point]);
                        bdMap.addOverlay(polylineMarker);
                        polyLineMarkers.push(polylineMarker);
                    }
                } else {
                    //对事件的处理
                    var evtMarker = createMarker.call(this, markerType.evtMarker, trackObj.point, {
                        evtMarker: {
                            data: trackObj.__data__
                        }
                    });
                    bdMap.addOverlay(evtMarker);
                    evtMarkers.push(evtMarker);
                }
                intervalId = setTimeout(arguments.callee.bind(this), optSettings.speed);
                //将来对正在播放的轨迹往回拉时，可以用到这个数据
                historyTrackData.push(trackObj);
                this.dispatch('processing', {
                    total: trackData.listTP.length,
                    current: historyTrackPoints.length
                });
            } else {
                //当播放完毕时，将gif动态图切换到png静态图
                var point = this.personMarker.getPosition();
                var iconImg = getPersonIcon(this);
                adjustmentPersonMarkerDir.call(this, {
                    lastNode: null,
                    point: point
                }, iconImg);

                //正常情况下轨迹播放完毕，触发事件，以便通知播放器本身(播放器根据设置可能自动播放下一轨迹)
                trackState.current = trackState.stop;
                this.dispatch(trackState.stop, {
                    evtType: trackState.stop,
                    target: this
                })
            }
        }

        //数据适配器
        this.dataAdapter = function(fn) {
            var lastNode = null;
            trackData.listTP = formatTrackData("ListTP", fn);
            trackData.listTP.sort(function(a, b) {
                return a.__time__ - b.__time__;
            });
            trackData.listTP.forEach(function(item, index) {
                if (index == 0) {
                    item.lastNode = null;
                    lastNode = item;
                } else {
                    item.lastNode = lastNode;
                    lastNode = item;
                }
            })
            trackData.listTE = formatTrackData("ListTE", fn);
            //人员轨迹跟案件合并，按时间排序，这样就解决了边播放巡查轨迹边陆续带出案件的功能
            trackData.allData = trackData.listTP.concat(trackData.listTE);
            trackData.allData.sort(function(a, b) {
                return a.__time__ - b.__time__;
            });
        }

        //当前轨迹的状态
        this.getState = function() {
            return trackState.current;
        }

        //设置播放速度
        this.setPlaySpeed = function(speed) {
            if (isNaN(speed))
                throw new Error("setPlaySpeed传进来的参数不是一个有效的速度值");
            optSettings.speed = speed
        }


        //开始绘制轨迹
        this.run = function() {
            if (!isHandleData) {
                throw new Error("未调用formatTrackData方法，格式化用户轨迹跟事件数据!");
            }

            if (trackData.allData.length > 0 && trackState.current != trackState.playing) {
                if (!this.personMarker) {
                    this.personMarker = createMarker.call(this, markerType.personMarker, trackData.allData[0].point);
                    bdMap.addOverlay(this.personMarker);
                }

                if (!numberMarker) {
                    numberMarker = createMarker.call(this, markerType.numberMarker, trackData.allData[0].point);
                    bdMap.addOverlay(numberMarker);
                }
                trackState.current = trackState.playing;
                drawTrack.call(this);
            }
        }

        //暂停绘制轨迹
        this.pause = function() {
            if (trackState.current == trackState.playing) {
                trackState.current = trackState.pause;
            }
        }

        //停止绘制轨迹
        this.stop = function() {
            if (trackState.current == trackState.playing || trackState.current == trackState.pause) {
                trackState.current = trackState.stop;
                this.dispose();
            }
        }

        //清除资源,当播放器调用stop方法时，则调用该方法
        this.dispose = function() {
            clearTimeout(intervalId);
            this.unAll();

            numberMarker && bdMap.removeOverlay(numberMarker);
            numberMarker = null;
            this.personMarker && bdMap.removeOverlay(this.personMarker);
            this.personMarker = null;
            for (var i = evtMarkers.length - 1; i >= 0; i--) {
                bdMap.removeOverlay(evtMarkers[i]);
                evtMarkers.splice(i, 1);
            }
            for (var i = polyLineMarkers.length - 1; i >= 0; i--) {
                bdMap.removeOverlay(polyLineMarkers[i]);
                polyLineMarkers.splice(i, 1);
            }
            historyTrackData.length = 0;
            historyTrackPoints.length = 0;
            trackData.listTP && (trackData.listTP.length = 0);
            trackData.listTE && (trackData.listTE.length = 0);
            trackData.allData && (trackData.allData.length = 0);
        }

    }


    legendofkage.Util.inherits(BaiduTrack, legendofkage.BaseTrack);

    BaiduTrack.prototype.personMarker = null;

    /**
     * 
     * 注册marker事件(主要是针对事件数据)
     * @param {any} type 
     * @param {any} callbackFn 
     */
    BaiduTrack.prototype.addEventListener = function(type, callbackFn) {
        if (type && typeof type == "string" && typeof callbackFn == "function")
            this.on("marker:" + type, callbackFn);
    }

    BaiduTrack.prototype.clearPersonMarker = function() {
        if (this.personMarker) {
            this.personMarker.getMap().removeOverlay(this.personMarker);
        }
        this.personMarker = null;
    }


    legendofkage.BaiduTrack = BaiduTrack;
    return legendofkage.BaiduTrack;
});